package com.fingard.dsp.bank.directbank.hsbc01;

import java.io.File;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.bankInterface.IBalance;
import com.fingard.dsp.bank.reqrespobj.balance.Req7505HisBalQry;
import com.fingard.dsp.bank.reqrespobj.balance.Req7506BalQry;
import com.fingard.dsp.bank.reqrespobj.balance.RetAts7505HisBalQry;
import com.fingard.dsp.bank.reqrespobj.balance.RetAts7506BalQry;
import com.fingard.dsp.bank.reqrespobj.balance.detail.RetAtsBalDetail;
import com.fingard.dsp.bank.reqrespobj.balance.detail.RetAtsHisBalDetail;
import com.fingard.io.FileHelper;
import com.fingard.text.StringHelper;

/**
 * @author XueJy on 2018/9/14.
 * @version 1.0
 */
public class HSBC01Balance extends HSBC01Base implements IBalance {

    /**
     * 今日余额查询 MT942
     */
    @Override
    public RetAts7506BalQry d_7506_BalQry(Req7506BalQry p_req7506) throws Exception {
        //创建返回对象
        RetAts7506BalQry retAts = new RetAts7506BalQry(p_req7506.reqHeader);
        //写返回ATS的统一头部信息
        retAts.writeStart();
        if("0".equals(this.getBankConfig().getValueAsString("channelFalg"))){//保险
            //查询账号
            String actNum = "";
            //查询币种
            String actCur = "";
            String actArea = "";
            //唯一流水号
//        String reqSeqId = p_req7506.reqHeader.transSeqID;
            downloadFile();
            String filePath942 = getTrimPath(getReceivePath(EnumDirType.MT942.getValue(), new Date()));
            while (p_req7506.readRecord()) {
                RetAtsBalDetail detail = new RetAtsBalDetail();
                actNum = p_req7506.readedDetail.actNum;
                actCur = convertCurToBank(p_req7506.readedDetail.actCur);
                actArea = p_req7506.readedDetail.actArea;
                detail.actCur = actCur;
                detail.actNum = actNum;
                detail.actArea = actArea;
                try {
                    // 读取银行返回余额文件信息，组装报文发给ATS
                    List<String> fileNames = getDirectoryAllFileName(filePath942);
                    String latestFilename = "";
                    //筛选出最新的MT942文件
                    Date latestDate = null;
                    Date receivedDate = null;
                    String year = Format.Date8Format.format(new Date()).substring(0, 4);
                    for (String fileName : fileNames) {
                        //MT942CN.EJ321.0719101358 52.088251418011.TXT
                        String[] msgInNames = fileName.split("\\.");
                        if (msgInNames.length >= 4) {
                            if (msgInNames[3].equals(actNum)) {
                                receivedDate = Format.DateTime14Format.parse(year + msgInNames[2].substring(0, 10));
                                if (latestDate == null) {
                                    latestDate = receivedDate;
                                    latestFilename = fileName;
                                } else if (receivedDate.getTime() > latestDate.getTime()) {
                                    latestDate = receivedDate;
                                    latestFilename = fileName;
                                }
                            }
                        } else {
                            WriteBankLogLn(fileName + "<---该MT942文件名有误");
                        }
                    }
                    if (!"".equals(latestFilename)) {
                        String contain = "";
                        synchronized (this) {
                            //读取文件内容
                            contain = FileHelper.readFileText(getTrimPath(filePath942) + File.separator + latestFilename, getCharset());
                        }
                        //对单个文件进行解析查找对应的账号明细信息 //"H", 明细头记录拆分符
                        String[] sArray1 = contain.split(":25:");
                        if (sArray1.length > 1 && sArray1[1].startsWith(actNum)) {
                            String spliter = "\n";
                            if (sArray1[1].contains("\r\n")) {
                                spliter  = "\r\n";
                            }
                            String[] lines = contain.split(spliter);
                            for (String line : lines) {
                                if (line.startsWith("BAL")) {
                                    //BAL PLGC8285818,18/CLGC26091469,45/CAVC26091469,45
                                    //PLGC Posted Ledger Amount
                                    //CLGC Current Ledger Amount
                                    // Available balance
                                    String[] bal = line.split("/");
                                    String currCdFlag = bal[1].substring(3,4);
                                    String availCdFlag = bal[2].substring(3,4);
                                    BigDecimal currBal = new BigDecimal(convertCommaToPoint(bal[1].substring(4)));
                                    BigDecimal availBal = new BigDecimal(convertCommaToPoint(bal[2].substring(4)));
                                    if ("D".equals(currCdFlag)) {
                                        currBal = currBal.multiply(new BigDecimal("-1"));
                                    }
                                    if ("D".equals(availCdFlag)) {
                                        availBal = availBal.multiply(new BigDecimal("-1"));
                                    }
                                    detail.respCode = "0";
                                    detail.frozenBal =  df.format(currBal.subtract(availBal));
                                    detail.availBal = df.format(availBal);
                                    detail.currBal = df.format(currBal);
                                    detail.respInfo = "";
                                    retAts.writeRetDetail(detail, p_req7506.isBatch);
                                }
                            }
                        }
                    }
                } catch (Exception ex) {
                    detail.respCode = "-1";
                    detail.respInfo = "账号:" + actNum + "查询今日余额信息异常:" + ex.getMessage();
                    retAts.writeRetDetail(detail, p_req7506.isBatch);
                    WriteBankLogLn("账号:" + actNum + "查询今日余额信息异常:" + ex.getMessage());

                }
            }
            retAts.writeEnd();
        }else {//企金
            while(p_req7506.readRecord()){
                //创建返回到ATS余额对象
                RetAtsBalDetail detail = new RetAtsBalDetail();
                //获取账号
                String accNum = p_req7506.readedDetail.actNum;
                //设置时间
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(new Date());
                String dealedFile = getBankConfig().getValueAsString("DealedPath")+ File.separator+
                        Format.Date8Format.format(calendar.getTime())+ File.separator+"MT942"+File.separator+accNum+"_7506.txt";
                //如果当天日间文件还没收到，就取前一天的日终文件，
                //如果前一天的日终文件没收到，说明是节假日，就继续往前遍历，最多10天
                int num =1;
                String day=getBankConfig().getValueAsString("countDay");//往前遍历天数
                while(!FileHelper.existFile(dealedFile)&&num<=Integer.parseInt(StringHelper.isNullOrEmpty(day) ?"10":day)){
                    WriteBankLogLn("账户"+accNum+"在"+calendar+"日期的MT940文件不存在,继续往前一天遍历，第"+num+"次");
                    calendar.add(Calendar.DAY_OF_MONTH,-1);
                    dealedFile = getBankConfig().getValueAsString("DealedPath")+File.separator+
                            Format.Date8Format.format(calendar.getTime())+File.separator+
                            "MT940"+File.separator+accNum+"_7505.txt";
                    num++;
                }
                if(!FileHelper.existFile(dealedFile)){
                    detail.respCode ="0";
                    detail.respInfo="此账号余额暂时无法获取";
                }
                WriteBankLogLn("遍历至此文件"+dealedFile);
                //读取文件内容
                String balanceContent = FileHelper.readFileText(dealedFile,getCharset());
                WriteBankLogLn("读取到的文件内容："+balanceContent);
                if(StringHelper.hasAnyChar(balanceContent)){
                    //账号|币种|当前余额|可用余额|昨日余额(MT940)
                    //账号|币种|当前余额|可用余额|期初余额|最后交易日期|文件生成时间|期初余额对应的日期(MT942)
                    String[] bal  =balanceContent.split("\\|");
                    detail.respCode ="0";
                    detail.actNum =bal[0].trim();
                    detail.actCur =convertCurToATS(bal[1].trim());
                    detail.availBal =bal[3].trim();
                    detail.currBal =bal[2].trim();
                    detail.yesterdayBal = bal[4].trim();
                }else {
                    detail.respCode="-1";
                    detail.respInfo="文件读取异常";
                }
                retAts.writeRetDetail(detail,p_req7506.isBatch);
            }
            retAts.writeEnd();
        }
        return retAts;
    }



    /**
     * 历史查询 MT940
     */

    @Override
    public RetAts7505HisBalQry d_7505_BalQry(Req7505HisBalQry p_req7505) throws Exception {
        if("0".equals(this.getBankConfig().getValueAsString("channelFalg"))) {//保险
            //创建返回对象
            RetAts7505HisBalQry retAts = new RetAts7505HisBalQry(p_req7505.reqHeader);
            //写返回ATS的统一头部信息
            retAts.writeStart();
            //待查询账号
            String actNum = p_req7505.actNum;
            String reqSeqId = p_req7505.reqHeader.transSeqID;
            String actCur = convertCurToBank(p_req7505.actCur);
            try {
                //昨日余额查询
                Calendar calendarFrom = Calendar.getInstance();
                calendarFrom.setTime(p_req7505.getDateFrom());
                Calendar calendarTo = Calendar.getInstance();
                calendarTo.setTime(p_req7505.getDateTo());
                if (calendarTo.getTime().getTime() > System.currentTimeMillis()) {
                    calendarTo.setTime(new Date());
                }
                Calendar amonthago = Calendar.getInstance();
                amonthago.setTime(new Date());
                //余额查询范围日期允许最大31天   MT940查询其实没限制
                amonthago.add(Calendar.MONTH, -1);
                if (calendarFrom.getTime().getTime() < amonthago.getTime().getTime()) {
                    calendarFrom = amonthago;
                }
                //存放历时余额详情Map Key为日期yyyy-MM-dd ,Value为当日余额
                int numOfDate = calendarTo.get(Calendar.DAY_OF_YEAR) - calendarFrom.get(Calendar.DAY_OF_YEAR) + 1;
                Map<String, String> prebalances = new HashMap<String, String>();
                for (int x = 0; x < numOfDate; x++) {
                    prebalances.put(Format.Date10Format.format(calendarFrom.getTime()), "");
                    calendarFrom.add(Calendar.DAY_OF_YEAR, 1);
                }
                downloadFile();
                //拷贝文件到本地路径
                for (Map.Entry<String, String> history : prebalances.entrySet()) {
                    String fileDatePath = getReceivePath(EnumDirType.MT940.getValue(), Format.Date8Format.parse(history.getKey().substring(0, 4) + history.getKey().substring(5, 7) + history.getKey().substring(8, 10)));
                    //指定日期路径yyyy-MM-dd

                    List<String> fileNames = getDirectoryAllFileName(fileDatePath);
                    //region 解析查询日期条件范围内的每日余额信息
                    for (String fileName : fileNames) {
                        String contain = "";
                        synchronized (this) {
                            //读取文件内容
                            contain = FileHelper.readFileText(getTrimPath(fileDatePath) + File.separator + fileName, getCharset());
                        }
                        //对单个文件进行解析查找对应的账号明细信息 //"H", 明细头记录拆分符
                        String[] sArray1 = contain.split(":25:");

                        if (sArray1.length > 1 && sArray1[1].startsWith(actNum)) {
                            String spliter = "\n";
                            if (sArray1[1].contains("\r\n")) {
                                spliter = "\r\n";
                            }
                            //62a Closing Balance (Booked Funds) 64 Closing Available Balance (Available Funds
                            DecimalFormat df = new DecimalFormat("0.00");
                            String[] balanceArray = sArray1[1].split(":62F:");
                            //:62F:C180919CNY20019492,89
                            //:64:C180919CNY20019492,89
                            if (balanceArray.length > 1) {
                                String cdFlag = balanceArray[1].substring(0, 1);
                                //C150619CNY852244385,85
                                String amt = balanceArray[1].substring(10, balanceArray[1].indexOf(spliter)).trim();
                                amt = convertCommaToPoint(amt);
                                if ("D".equals(cdFlag)) {
                                    amt = "-" + amt;
                                }

                                BigDecimal balance = new BigDecimal(amt);
                                history.setValue(df.format(balance));

                                break;
                            }
                        }
                    }
                }
                for (Map.Entry<String, String> history : prebalances.entrySet()) {
                    RetAtsHisBalDetail retDetail = new RetAtsHisBalDetail();
                    retDetail.actBal = history.getValue();
                    //余额日期 yyyy-MM-dd
                    retDetail.balDate = history.getKey();
                    //历史余额、此余额是返回当前总余额还是当前可用余额
                    retAts.writeRetDetail(retDetail);
                }
            } catch (Exception e) {
                if (!retAts.hasWrittenRespCode) {
                    retAts.writeRespCode("-1");
                }
                if (!retAts.hasWrittenRespInfo) {
                    retAts.writeRespInfo(e.getMessage());
                }
                retAts.writeEnd();
                return retAts;
            }
            if (retAts.getWrittenRdCount() == 0) {
                if (!retAts.hasWrittenRespCode) {
                    retAts.writeRespCode("0");
                }
                if (!retAts.hasWrittenRespInfo) {
                    retAts.writeRespInfo("返回结果为空，所查询时间段内不存在历史余额");
                }
                retAts.writeEnd();
                return retAts;
            }
            retAts.writeEnd();
            return retAts;
        }else {
            //查询时间校验
            String[] dateAry=getQueryDate(p_req7505.dateFrom,p_req7505.dateTo);
            p_req7505.dateFrom=dateAry[0];
            p_req7505.dateTo=dateAry[1];
            //创建返回对象
            RetAts7505HisBalQry retAts = new RetAts7505HisBalQry(p_req7505.reqHeader);
            //写返回ATS的统一头部信息
            retAts.writeStart();
            String tmpRespCode = "";
            String tmpRespInfo = "";
            try{
                String accNum = p_req7505.actNum;
                Date dateStart = Format.Date8Format.parse(p_req7505.dateFrom);
                Date dateEnd = Format.Date8Format.parse(p_req7505.dateTo);
                Calendar calendar=Calendar.getInstance();
                while (!dateStart.after(dateEnd)){
                    String dealedPath = getBankConfig().getValueAsString("DealedPath")+File.separator+
                            Format.Date8Format.format(dateStart)+File.separator+"MT940"+File.separator+
                            accNum+"_7505.txt";
                    if(!FileHelper.existFile(dealedPath)){
                        calendar.setTime(dateStart);
                        calendar.add(Calendar.DAY_OF_MONTH, 1);
                        dateStart = calendar.getTime();
                        continue;
                    }
                    //读取文件内容
                    String balanceContent = FileHelper.readFileText(dealedPath,getCharset());
                    WriteBankLogLn("读取到的文件内容："+balanceContent);
                    if(StringHelper.hasAnyChar(balanceContent)){
                        //账号|币种|当前余额|可用余额|昨日余额(MT940)|页码
                        String[] bal  =balanceContent.split("\\|");
                        RetAtsHisBalDetail tmpRetDetail = new RetAtsHisBalDetail();
                        tmpRetDetail.actBal=bal[2].trim();
                        tmpRetDetail.availBal=bal[3].trim();
                        tmpRetDetail.balDate=Format.Date10Format.format(dateStart);
                        retAts.writeRetDetail(tmpRetDetail);
                    }else {
                        tmpRespCode="-1";
                        tmpRespInfo="文件读取异常";
                    }
                    calendar.setTime(dateStart);
                    calendar.add(Calendar.DAY_OF_MONTH, 1);
                    dateStart = calendar.getTime();
                }
            } catch (Exception e) {
                tmpRespCode = "-1";
                tmpRespInfo = e.getMessage();
                e.printStackTrace();
            }
            if (tmpRespCode.equals("-1")) {
                retAts = new RetAts7505HisBalQry(p_req7505.reqHeader);
                retAts.writeStart();//写返回ATS的统一头部信息
                retAts.writeRespCode(tmpRespCode);
                retAts.writeRespInfo(tmpRespInfo);
            } else if (retAts.getWrittenRdCount() == 0) {
                retAts.writeRespCode("0");
                retAts.writeRespInfo("返回结果为空，所查询时间段内不存在历史余额");
            }
            retAts.writeEnd();
            return retAts;
        }
    }
}
